import fnmatch
import logging
import os
import time

from django.conf import settings
from django_apscheduler.models import DjangoJob

from mars.apps.scheduler.models import AUTOBACKUP_JOB_ID, SchedulerJob
from mars.apps.scheduler.views import (add_job, modify_job, pause_job,
                                       resume_job)
from mars.utils.db import backup_db as backup_database
from mars.utils.exceptions.enums import StatusCodeEnum
from mars.utils.exceptions.exceptions import APIException

# 获取在配置文件中定义的logger，用来记录日志
logger = logging.getLogger("django")


def backup_db(params):
    database = settings.DATABASES['default']
    host = database['HOST']
    dbname = database['NAME']
    user = database['USER']
    password = database['PASSWORD']
    bakfile = "mars_%d.sql" % int(time.time())
    path = os.path.join(os.path.dirname(settings.BASE_DIR), "db_bak",bakfile).replace('\\','/')
    result = backup_database(username=user,password=password,db=dbname,filename=path,host=host)
    if len(result)>0 :
        logger.error(result,exc_info=True)
    else:
        file_times = []
        # 删除多余的备份，备份文件只保留3天的文件
        for f_name in os.listdir(os.path.join(os.path.dirname(settings.BASE_DIR), "db_bak").replace('\\','/')):
            if fnmatch.fnmatch(f_name, 'mars_*.sql'):
                #截取除文件名的时间部分
                str = f_name.split(".")[0].split("_")[1]
                file_times.append(int(str))
        if len(file_times) >=3:
            file_name = "mars_%d.sql" % min(file_times)
            del_file_path = os.path.join(os.path.dirname(settings.BASE_DIR), "db_bak",file_name).replace('\\','/')
            logger.info("删除备份文件"+del_file_path)
            os.remove(del_file_path)
    return result


def start(begin_time):
    # 查询job是否已存在,不存在则创建
    if DjangoJob.objects.filter(id=AUTOBACKUP_JOB_ID).count() > 0:
        resume_job(AUTOBACKUP_JOB_ID,{"begin_time":begin_time})
    else:
        add_job("mars.apps.systems.services:backup_db",{"id":AUTOBACKUP_JOB_ID,"name":"数据库自动备份","begin_time":begin_time})

def stop():
    pause_job(AUTOBACKUP_JOB_ID)
def restart(begin_time):
    resume_job(AUTOBACKUP_JOB_ID,{"begin_time":begin_time})

def myself_backup():
    database = settings.DATABASES['default']
    host = database['HOST']
    dbname = database['NAME']
    user = database['USER']
    password = database['PASSWORD']
    bakfile = "manual_mars_%d.sql" % int(time.time())
    path = os.path.join(os.path.dirname(settings.BASE_DIR), "db_bak",bakfile).replace('\\','/')
    result = backup_database(username=user,password=password,db=dbname,filename=path,host=host)
    return {"result":result,"file":path}
    
def update_job(status,backup_time=None):
    job = SchedulerJob.objects.filter(job_id = AUTOBACKUP_JOB_ID).first()
    if not job:
            raise APIException(StatusCodeEnum.NODATA_ERR)
    job.status = status
    if backup_time:
        job.begin_time = backup_time
    job.save()

def backup_dispatch(params):
    backup_time = params.get('backup_time','01:00')
    mode = params.get('mode')
    success = True
    msg = ""
    try:
        if mode == "1":
            start(backup_time)
            update_job(1,backup_time=backup_time)
        elif mode == "2":
            stop()
            update_job(2)
        elif mode == "3":
            restart(backup_time)
            update_job(1,backup_time=backup_time)
        elif mode == "4":
            result = myself_backup()
            if len(result['result'])>0 :
                success = False
                msg = result['result']
            else:
                msg = result['file']
        return{"success":success,"msg":msg}
    except Exception as e:
        logger.error(e)
        return{"success":False,"msg":e}